import org.geotools.data.*;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import java.util.ArrayList;
import java.util.List;

public class Shpfile2PostGIS {
    DataStore mcPGDataSotre=null;
    SimpleFeatureCollection mcShpCollection=null;

    private void initImportParms(String pPath_Shp) throws Exception {
        //初始化待导入shp数据
//        ShpfileReader lpReader_Source=new ShpfileReader();
//        mcShpCollection=lpReader_Source.getShpfileData(pPath_Shp);//已经修改为static方式了
        mcShpCollection=ShpfileReader.getShpfileData(pPath_Shp);
        //初始化目标库连接
        mcPGDataSotre=connPostGIS.connDB();
    }

    /* 另外一种方法，暂时还未解决问题，不知道是否可用
    //这个方法可以创建类，但是无法导入数据，不知道原因
    public void ShpImport(String pPath_ShpSource) {
        try {
            //(1)首先初始化导入参数
            initImportParms(pPath_ShpSource);
            //(2)开始执行导入
            SimpleFeatureType sft = mcShpCollection.getSchema();
            //创建要素模板
            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
            //设置坐标系
            tb.setCRS(DefaultGeographicCRS.WGS84);
            tb.setName("shpfile8");
            tb.setAttributes(sft.getAttributeDescriptors());
            SimpleFeatureType targetType = tb.buildFeatureType();
            String tmp = targetType.getTypeName();
            //创建
//            mcPGDataSotre.createSchema(tb.buildFeatureType());
            mcPGDataSotre.createSchema(targetType);
            //设置编码(在创建的PostGIS中没有这个属性)
            // mcPGDataSotre.setCharset(Charset.forName("utf8"));
            //开启事务
            Transaction lpTransTarget = new DefaultTransaction();
            SimpleFeatureStore fstoreTarget = (SimpleFeatureStore) mcPGDataSotre.getFeatureSource(targetType
                    .getTypeName());
            fstoreTarget.setTransaction(lpTransTarget);
            //设置Writer，并设置为自动提交
            FeatureWriter<SimpleFeatureType, SimpleFeature> writerTarget =
                    mcPGDataSotre.getFeatureWriter(mcPGDataSotre.getTypeNames()[0], Transaction.AUTO_COMMIT);
            //循环写入要素
            SimpleFeatureIterator itertorSource = mcShpCollection.features();
            int lpCounts = 0;
            while (itertorSource.hasNext()) {
                //获取要写入的要素
                SimpleFeature featureSource = itertorSource.next();
                //将要写入位置
                SimpleFeature featureBufTarget = writerTarget.next();//这一句有问题
                //设置写入要素所有属性
                featureBufTarget.setAttributes(featureSource.getAttributes());
                fstoreTarget.addFeatures(DataUtilities.collection(featureBufTarget));
                lpCounts++;
}
            System.out.println("成功导入要素" + lpCounts + "个。");
                    lpTransTarget.commit();
                    lpTransTarget.close();
                    //释放数据库连接
                    mcPGDataSotre.dispose();
//            //再结束后一次性将所有数据写入
//            writerTarget.write();
//            //关闭写入流
//            writerTarget.close();
                    itertorSource.close();
                    } catch (Exception e) {
                    e.printStackTrace();
                    }
                    }

private String importDataIntoStore(SimpleFeatureCollection feaCollSource, String name
    ) throws Throwable {
        // grab the data store
        //在这里直接使用传入的目标库的DataStore
// DataStore ds = (DataStore) storeInfo.getDataStore(null);
        //创建目标库的FeatureType;如果name是nullname则直接采用原始的sourceType
        SimpleFeatureType sourceType = feaCollSource.getSchema();
        if (name != null) {
            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
            tb.init(sourceType);
            tb.setName(name);
            sourceType = tb.buildFeatureType();
        }
        //根据type创建目标库的Schema
        mcPGDataSotre.createSchema(sourceType);
        // try to get the target feature type (might have slightly different name and structure)
        SimpleFeatureType targetType = mcPGDataSotre.getSchema(sourceType.getTypeName());
        if (targetType == null) {
            // ouch, the name was changed... we can only guess now...
            // try with the typical Oracle mangling
            targetType = mcPGDataSotre.getSchema(sourceType.getTypeName().toUpperCase());
        }
        //如果创建了之后仍然时空，此时报错
        if (targetType == null) {
            throw new Throwable("The target schema was created, but with a name "
                    +"that we cannot relate to the one we provided the data store. Cannot proceeed further");
        }
        //这里应该还增加一个判断：目标层是否已经存在
        // try to establish a mapping with old and new attributes. This is again
        // just guesswork until we have a geotools api that will give us the
        // exact mapping to be performed
        //建立原始shp层和目标层的字段对应关系
        Map<String, String> mapping = buildAttributeMapping(sourceType, targetType);
        //创建事务并开始导入要素
        Transaction lpTransTarget = new DefaultTransaction();
        SimpleFeatureStore fstoreTarget = (SimpleFeatureStore) mcPGDataSotre.getFeatureSource(targetType
                .getTypeName());
        fstoreTarget.setTransaction(lpTransTarget);
        SimpleFeatureIterator fiSource = feaCollSource.features();
        SimpleFeatureBuilder fbTarget = new SimpleFeatureBuilder(targetType);
        while (fiSource.hasNext()) {
            SimpleFeature source = fiSource.next();
            fbTarget.reset();
            for (String sname : mapping.keySet()) {
                fbTarget.set(mapping.get(sname), source.getAttribute(sname));
            }
            SimpleFeature target = fbTarget.buildFeature(null);
            fstoreTarget.addFeatures(DataUtilities.collection(target));
        }
        lpTransTarget.commit();
        lpTransTarget.close();
        //释放数据库连接
        mcPGDataSotre.dispose();
        return "Import Succeed";
    }


     */

    public void ShpImport2(String pPath_ShpSource) {
        try {
            //(1)首先初始化导入参数
            initImportParms(pPath_ShpSource);
            //(2)开始执行导入
            SimpleFeatureType sft = mcShpCollection.getSchema();
            //创建要素模板
            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
            //设置坐标系
            tb.setCRS(DefaultGeographicCRS.WGS84);
            tb.setName("shpfile15");
            tb.setAttributes(sft.getAttributeDescriptors());
            SimpleFeatureType targetType = tb.buildFeatureType();
            String tmp = targetType.getTypeName();
            mcPGDataSotre.createSchema(targetType);
            //批量导入要素
            SimpleFeatureIterator itertorSource = mcShpCollection.features();
            int lpCounts = 0;
            List<SimpleFeature> fea2Imped=new ArrayList<SimpleFeature>();
            while (itertorSource.hasNext()) {
                //获取要写入的要素
                SimpleFeature featureSource = itertorSource.next();
                fea2Imped.add(featureSource);
                if (fea2Imped.size()>10) {
                    lpCounts=fea2Imped.size();
                    break;
                }
            }
            SimpleFeatureStore lpsfs=(SimpleFeatureStore) mcPGDataSotre.getFeatureSource(targetType.getTypeName());
            SimpleFeatureCollection lpColl=new ListFeatureCollection(targetType,fea2Imped);
            Transaction lpTransactionTarget=new DefaultTransaction("create");
            lpsfs.setTransaction(lpTransactionTarget);
            try {
                lpsfs.addFeatures(lpColl);
                lpTransactionTarget.commit();
            } catch (Exception problem) {
                problem.printStackTrace();
                lpTransactionTarget.rollback();
            } finally {
                lpTransactionTarget.close();
                itertorSource.close();
            }
            System.out.println("成功导入要素" + lpCounts + "个。");
            //释放数据库连接
            mcPGDataSotre.dispose();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
